import React, { useState, useEffect, useCallback } from "react";
import { Button } from "antd";
import SparkMD5 from "spark-md5";

const calculateHash = (chunk: Blob): Promise<string> => {
  return new Promise((resolve, reject) => {
    const spark = new SparkMD5.ArrayBuffer();
    const reader = new FileReader();
    reader.onload = (e) => {
      if (e.target?.result) {
        spark.append(e.target.result as ArrayBuffer);
        resolve(spark.end());
      } else {
        reject(new Error("Failed to read chunk"));
      }
    };
    reader.onerror = () => reject(new Error("FileReader error"));
    reader.readAsArrayBuffer(chunk);
  });
};

export const LargeFileSlice = () => {
  const [file, setFile] = useState<File | null>(null);

  const readAndCalculateHash = useCallback(() => {
    if (!file) return;
    const chunkSize = 1024 * 1024;
    const chunkCount = Math.ceil(file.size / chunkSize);
    const stream = new ReadableStream({
      async start(controller) {
        for (let i = 0; i < chunkCount; i++) {
          const start = i * chunkSize;
          const end = start + chunkSize;
          const chunk = file.slice(start, end);
          // 使用spark-md5计算分片hash
          const hash = await calculateHash(chunk);
          controller.enqueue(hash);
        }
        controller.close();
      },
    });
  }, [file]);

  const oneTimeCalculateHash = useCallback(() => {
    if (!file) return;
    const hash = file.hash;
  }, [file]);

  return (
    <div className="flex flex-col gap-4">
      <input
        type="file"
        value={file?.name}
        onChange={(e) => setFile(e.target.files?.[0] || null)}
      />
      <div className="flex gap-4">
        <div>
          <Button onClick={readAndCalculateHash}>边读边计算分片hash</Button>
        </div>
        <div>
          <Button onClick={oneTimeCalculateHash}>一次性计算总hash</Button>
        </div>
      </div>
      <div>
        <p>计算完成</p>
        <p>文件信息</p>
        <p>文件名</p>
        <p>文件类型</p>
        <p>文件大小</p>
        <p>文件hash</p>
      </div>
    </div>
  );
};
